package org.rexsong.example.quartzsample.config;

import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.rexsong.example.quartzsample.domain.Jobs;
import org.rexsong.example.quartzsample.jobs.simple.SimpleJob;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Configuration
public class SchedulerConfig implements JobListener {

    private static final String JOB_NAME = "MY_JOB";
    private static final String SCHEDULER_SERVICE_GROUP = "SCHEDULER_SERVICE";
    @Autowired
    private Scheduler scheduler;

    @Autowired
    private List<Jobs> jobsList;

    @PostConstruct
    private void init() throws SchedulerException {
        scheduler.getListenerManager().addJobListener(this, GroupMatcher.groupEquals(SCHEDULER_SERVICE_GROUP));
        Map<JobDetail, Trigger> jobMap = jobsList.stream().collect(Collectors.toMap(job -> {
            try {
                return JobBuilder.newJob((Class<? extends Job>) Class.forName(job.getJobClass()))
                        .requestRecovery()
                        .storeDurably()
                        .withIdentity(job.getJobName(), SCHEDULER_SERVICE_GROUP)
                        .withDescription(job.getJobDescription())
                        .build();
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
        }, job-> {
            return TriggerBuilder.newTrigger()
                    .withSchedule(CronScheduleBuilder.cronSchedule(job.getJobSchedule()))
                    .withIdentity(job.getJobName(), SCHEDULER_SERVICE_GROUP)
                    .build();
        }));
        jobMap.forEach((key, value) -> {
            try {
                scheduler.scheduleJob(key, value);
            } catch (SchedulerException e) {
                throw new RuntimeException(e);
            }
        });
    }

    @Override
    public String getName() {
        return SCHEDULER_SERVICE_GROUP;
    }

    @Override
    public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {
        String jobId = jobExecutionContext.getJobDetail().getKey().getName();
        System.out.println(String.format("Job %s to be executed", jobId));
    }

    @Override
    public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {
        String jobId = jobExecutionContext.getJobDetail().getKey().getName();
        System.out.println(String.format("Job %s execute vetoed", jobId));
    }

    @Override
    public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException e) {
        String jobId = jobExecutionContext.getJobDetail().getKey().getName();
        System.out.println(String.format("Job %s was executed", jobId));
    }
}
